examples: add tanstack start with better auth example#6352
Conversation
📝 WalkthroughWalkthroughAdds a complete new example React + TanStack Start project demonstrating GitHub OAuth integration via Better Auth, including routing architecture, protected routes, session management, and environment configuration. No modifications to existing codebases; purely additive example scaffolding. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Fix all issues with AI agents
In @examples/react/start-basic-better-auth/package.json:
- Around line 1-32: Replace the pinned versions for the internal TanStack
packages so the example uses workspace packages: change the dependency entries
for "@tanstack/react-router", "@tanstack/react-router-devtools", and
"@tanstack/react-start" from their current "^1.147.0" values to "workspace:*" so
the example builds against the monorepo workspace versions.
In @examples/react/start-basic-better-auth/src/components/NotFound.tsx:
- Line 3: The children prop in the NotFound component is typed as any; update
the signature in export function NotFound({ children }: { children?: any }) to
use React.ReactNode instead (e.g., { children?: React.ReactNode }) and add the
appropriate import (either import React from 'react' or import type { ReactNode
} from 'react' and use ReactNode) so the file compiles under TypeScript strict
mode; keep the change scoped to the NotFound component signature and imports.
In @examples/react/start-basic-better-auth/src/routes/__root.tsx:
- Around line 81-85: The sign-out flow in handleSignOut lacks error handling;
wrap the async sequence (authClient.signOut, router.invalidate, router.navigate)
in a try/catch/finally: attempt signOut and only navigate on success, catch and
log the error (and surface user feedback via UI toast or set an error state) if
signOut fails, and call router.invalidate in finally to ensure client state is
refreshed regardless of outcome; reference handleSignOut, authClient.signOut,
router.invalidate, and router.navigate when making these changes.
In @examples/react/start-basic-better-auth/src/routes/protected.tsx:
- Around line 47-52: The code renders the entire session object via
JSON.stringify(session) which can leak sensitive tokens; update the JSX to avoid
printing full session: either gate the debug block behind a development-only
flag (e.g., process.env.NODE_ENV === "development") or replace
JSON.stringify(session, null, 2) with a redacted subset such as JSON.stringify({
user: { name: session?.user?.name, email: session?.user?.email } }, null, 2);
ensure you still reference the same session variable and keep the debug wrapper
conditional so it never shows in production.
In @examples/react/start-basic-better-auth/src/utils/auth.ts:
- Around line 10-11: Replace the non-null assertions for
process.env.GITHUB_CLIENT_ID and process.env.GITHUB_CLIENT_SECRET with a runtime
check that validates these env vars at startup: read
process.env.GITHUB_CLIENT_ID and process.env.GITHUB_CLIENT_SECRET into
variables, if either is missing throw or log a clear error (e.g.,
"GITHUB_CLIENT_ID is required") and exit, then use those validated variables for
clientId and clientSecret; reference the clientId/clientSecret fields in the
exported auth config (or the function that builds it) so the values are
guaranteed present.
- Around line 7-25: The Better Auth config in the exported auth (created via
betterAuth) is missing baseURL and trustedOrigins which breaks OAuth/CSRF in
production; update the betterAuth call for auth to include baseURL:
process.env.BETTER_AUTH_URL and trustedOrigins: [process.env.BETTER_AUTH_URL]
(or an array of allowed origins including localhost/dev and production URLs)
alongside the existing socialProviders and plugins, and then add the
corresponding BETTER_AUTH_URL (and any additional allowed origins) to your
environment files/.env.example.
🧹 Nitpick comments (11)
examples/react/start-basic-better-auth/.gitignore (1)
1-6: LGTM; consider widening env ignores to.env.*(while keeping.env.example).
Current rules are fine; if you want to prevent accidental commits of.env.development/.env.production, consider adding.env.*and a negation for.env.example.examples/react/start-basic-better-auth/tsconfig.json (1)
1-24: Strict TS config looks good; consider addingforceConsistentCasingInFileNames.
This helps avoid case-only import bugs that show up on CI/Linux but not on macOS/Windows.Proposed diff
{ "compilerOptions": { "target": "ES2022", "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": true, "noUnusedLocals": true, "noUnusedParameters": true, "noFallthroughCasesInSwitch": true, + "forceConsistentCasingInFileNames": true, "allowSyntheticDefaultImports": true, "baseUrl": ".", "paths": { "~/*": ["./src/*"] } }, "include": ["src", "env.d.ts", "vite.config.ts"] }examples/react/start-basic-better-auth/vite.config.ts (1)
9-10: Consider removingstrictPortfor better developer experience.Setting
strictPort: truewill cause the dev server to fail immediately if port 10000 is already in use. For an example project, this might be overly strict and could frustrate developers who have other services running on that port. Consider removing this option or setting it tofalseto allow Vite to find an available port automatically.♻️ More flexible configuration
server: { port: 10000, - strictPort: true, },examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
100-105: Optional chaining is redundant within the conditional block.Since
routeContext.sessionis already verified as truthy on line 100, the optional chaining onrouteContext.session?.user?.nameandrouteContext.session?.user?.emailis redundant. While this doesn't cause issues, simplifying torouteContext.session.user?.nameimproves code clarity.♻️ Simplify optional chaining
{routeContext.session ? ( <> <span className="text-gray-600"> - {routeContext.session?.user?.name || - routeContext.session?.user?.email} + {routeContext.session.user?.name || + routeContext.session.user?.email} </span>examples/react/start-basic-better-auth/.env.example (1)
1-3: Consider adding secret generation instructions.The comment mentions the minimum length requirement, but developers might benefit from guidance on how to generate a secure secret. Consider adding a comment with a command they can run.
📝 Enhanced documentation
# Better Auth Configuration -BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars-long +# Generate a secure secret with: openssl rand -base64 32 +BETTER_AUTH_SECRET=your-secret-key-here-min-32-chars-longexamples/react/start-basic-better-auth/src/router.tsx (1)
11-12: Use consistent component reference pattern.The
defaultErrorComponentuses a direct component reference whiledefaultNotFoundComponentwraps the component in an inline arrow function. This inconsistency creates a new component instance on each evaluation and could interfere with hot module replacement during development.♻️ Make component references consistent
defaultPreload: "intent", defaultErrorComponent: DefaultCatchBoundary, - defaultNotFoundComponent: () => <NotFound />, + defaultNotFoundComponent: NotFound, scrollRestoration: true,examples/react/start-basic-better-auth/src/routes/login.tsx (1)
14-19: Consider error handling for authentication failures.The
authClient.signIn.social()call has no error handling. If the OAuth flow fails (network error, user denies permission, etc.), the user receives no feedback.♻️ Recommended enhancement with error handling
function Login() { + const [error, setError] = React.useState<string | null>(null); + const handleGitHubSignIn = () => { - authClient.signIn.social({ - provider: "github", - callbackURL: "/", - }); + setError(null); + authClient.signIn.social({ + provider: "github", + callbackURL: "/", + }).catch((err) => { + setError("Failed to sign in. Please try again."); + console.error("Sign-in error:", err); + }); }; return ( <div className="max-w-md mx-auto mt-10"> <h1 className="text-2xl font-bold mb-6 text-center">Sign In</h1> + {error && ( + <div className="mb-4 p-3 bg-red-100 text-red-700 rounded"> + {error} + </div> + )} + <div className="space-y-4">examples/react/start-basic-better-auth/src/routes/index.tsx (1)
27-33: Validate image URLs to prevent potential security risks.The user avatar is rendered directly from
user.imagewithout validation. While GitHub OAuth typically returns trusted URLs, it's a good practice to validate image sources to prevent potential SSRF or content injection if the OAuth provider's data is compromised or the provider is changed.Consider adding URL validation or using a Content Security Policy to restrict image sources to trusted domains (e.g., GitHub's CDN).
examples/react/start-basic-better-auth/src/routes/protected.tsx (2)
3-10: Preserve “return to” intent on auth redirect (better UX).
Right now unauthenticated users always land on/loginwith no way to return to/protectedafter signing in; consider passing asearchparam (e.g.next=/protected) and consuming it in the login flow.Proposed change
export const Route = createFileRoute("/protected")({ beforeLoad: ({ context }) => { if (!context.session) { - throw redirect({ to: "/login" }); + throw redirect({ + to: "/login", + search: { next: "/protected" }, + }); } }, component: Protected, });
33-41: Harden avatar rendering (privacy/perf).
Consider addingloading="lazy",referrerPolicy="no-referrer"(common for 3rd-party avatars), and explicitwidth/heightto reduce layout shift.examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)
39-48: Optional: make “Go Back” more robust when history is empty.
window.history.back()can no-op on first-entry pages; consider falling back torouter.navigate({ to: '/' })(or just let the Link navigate) whenhistory.length <= 1.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
examples/react/start-basic-better-auth/.env.exampleexamples/react/start-basic-better-auth/.gitignoreexamples/react/start-basic-better-auth/README.mdexamples/react/start-basic-better-auth/package.jsonexamples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsxexamples/react/start-basic-better-auth/src/components/NotFound.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.tsexamples/react/start-basic-better-auth/src/router.tsxexamples/react/start-basic-better-auth/src/routes/__root.tsxexamples/react/start-basic-better-auth/src/routes/api/auth/$.tsexamples/react/start-basic-better-auth/src/routes/index.tsxexamples/react/start-basic-better-auth/src/routes/login.tsxexamples/react/start-basic-better-auth/src/routes/protected.tsxexamples/react/start-basic-better-auth/src/styles/app.cssexamples/react/start-basic-better-auth/src/utils/auth-client.tsexamples/react/start-basic-better-auth/src/utils/auth.tsexamples/react/start-basic-better-auth/tsconfig.jsonexamples/react/start-basic-better-auth/vite.config.ts
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Use TypeScript strict mode with extensive type safety for all code
Files:
examples/react/start-basic-better-auth/src/router.tsxexamples/react/start-basic-better-auth/src/routes/api/auth/$.tsexamples/react/start-basic-better-auth/src/routes/index.tsxexamples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsxexamples/react/start-basic-better-auth/src/utils/auth.tsexamples/react/start-basic-better-auth/src/routes/__root.tsxexamples/react/start-basic-better-auth/src/components/NotFound.tsxexamples/react/start-basic-better-auth/src/utils/auth-client.tsexamples/react/start-basic-better-auth/vite.config.tsexamples/react/start-basic-better-auth/src/routes/protected.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.tsexamples/react/start-basic-better-auth/src/routes/login.tsx
**/*.{js,ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Implement ESLint rules for router best practices using the ESLint plugin router
Files:
examples/react/start-basic-better-auth/src/router.tsxexamples/react/start-basic-better-auth/src/routes/api/auth/$.tsexamples/react/start-basic-better-auth/src/routes/index.tsxexamples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsxexamples/react/start-basic-better-auth/src/utils/auth.tsexamples/react/start-basic-better-auth/src/routes/__root.tsxexamples/react/start-basic-better-auth/src/components/NotFound.tsxexamples/react/start-basic-better-auth/src/utils/auth-client.tsexamples/react/start-basic-better-auth/vite.config.tsexamples/react/start-basic-better-auth/src/routes/protected.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.tsexamples/react/start-basic-better-auth/src/routes/login.tsx
**/package.json
📄 CodeRabbit inference engine (AGENTS.md)
Use workspace protocol
workspace:*for internal dependencies in package.json files
Files:
examples/react/start-basic-better-auth/package.json
🧠 Learnings (9)
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{js,ts,tsx} : Implement ESLint rules for router best practices using the ESLint plugin router
Applied to files:
examples/react/start-basic-better-auth/src/router.tsxexamples/react/start-basic-better-auth/src/routes/api/auth/$.tsexamples/react/start-basic-better-auth/src/routes/index.tsxexamples/react/start-basic-better-auth/src/routes/__root.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-10-08T08:11:47.088Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5402
File: packages/router-generator/tests/generator/no-formatted-route-tree/routeTree.nonnested.snapshot.ts:19-21
Timestamp: 2025-10-08T08:11:47.088Z
Learning: Test snapshot files in the router-generator tests directory (e.g., files matching the pattern `packages/router-generator/tests/generator/**/routeTree*.snapshot.ts` or `routeTree*.snapshot.js`) should not be modified or have issues flagged, as they are fixtures used to verify the generator's output and are intentionally preserved as-is.
Applied to files:
examples/react/start-basic-better-auth/src/router.tsxexamples/react/start-basic-better-auth/src/routes/protected.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Applies to **/*.{ts,tsx} : Use TypeScript strict mode with extensive type safety for all code
Applied to files:
examples/react/start-basic-better-auth/tsconfig.json
📚 Learning: 2025-11-02T16:16:24.898Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 5732
File: packages/start-client-core/src/client/hydrateStart.ts:6-9
Timestamp: 2025-11-02T16:16:24.898Z
Learning: In packages/start-client-core/src/client/hydrateStart.ts, the `import/no-duplicates` ESLint disable is necessary for imports from `#tanstack-router-entry` and `#tanstack-start-entry` because both aliases resolve to the same placeholder file (`fake-start-entry.js`) in package.json during static analysis, even though they resolve to different files at runtime.
Applied to files:
examples/react/start-basic-better-auth/tsconfig.jsonexamples/react/start-basic-better-auth/src/routeTree.gen.tsexamples/react/start-basic-better-auth/package.json
📚 Learning: 2025-12-25T13:04:55.492Z
Learnt from: nlynzaad
Repo: TanStack/router PR: 6215
File: e2e/react-start/custom-basepath/package.json:13-17
Timestamp: 2025-12-25T13:04:55.492Z
Learning: In the TanStack Router repository, e2e test scripts are specifically designed to run in CI (which uses a Unix environment), so Unix-specific commands (like `rm -rf`, `&` for backgrounding, and direct environment variable assignments without `cross-env`) are acceptable in e2e test npm scripts.
Applied to files:
examples/react/start-basic-better-auth/.gitignoreexamples/react/start-basic-better-auth/package.json
📚 Learning: 2025-10-01T18:31:35.420Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 5330
File: e2e/react-start/custom-basepath/src/routeTree.gen.ts:58-61
Timestamp: 2025-10-01T18:31:35.420Z
Learning: Do not review files named `routeTree.gen.ts` in TanStack Router repositories, as these are autogenerated files that should not be manually modified.
Applied to files:
examples/react/start-basic-better-auth/.gitignoreexamples/react/start-basic-better-auth/src/routes/protected.tsxexamples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-17T02:17:55.086Z
Learnt from: schiller-manuel
Repo: TanStack/router PR: 6120
File: packages/router-generator/src/generator.ts:654-657
Timestamp: 2025-12-17T02:17:55.086Z
Learning: In `packages/router-generator/src/generator.ts`, pathless_layout routes must receive a `path` property when they have a `cleanedPath`, even though they are non-path routes. This is necessary because child routes inherit the path from their parent, and without this property, child routes would not have the correct full path at runtime.
Applied to files:
examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-21T12:52:35.231Z
Learnt from: Sheraff
Repo: TanStack/router PR: 6171
File: packages/router-core/src/new-process-route-tree.ts:898-898
Timestamp: 2025-12-21T12:52:35.231Z
Learning: In `packages/router-core/src/new-process-route-tree.ts`, the matching logic intentionally allows paths without trailing slashes to match index routes with trailing slashes (e.g., `/a` can match `/a/` route), but not vice-versa (e.g., `/a/` cannot match `/a` layout route). This is implemented via the condition `!pathIsIndex || node.kind === SEGMENT_TYPE_INDEX` and is a deliberate design decision to provide better UX by being permissive with missing trailing slashes.
Applied to files:
examples/react/start-basic-better-auth/src/routeTree.gen.ts
📚 Learning: 2025-12-06T15:03:07.223Z
Learnt from: CR
Repo: TanStack/router PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-06T15:03:07.223Z
Learning: Use file-based routing in `src/routes/` directories or code-based routing with route definitions
Applied to files:
examples/react/start-basic-better-auth/src/routeTree.gen.ts
🧬 Code graph analysis (6)
examples/react/start-basic-better-auth/src/router.tsx (3)
examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)
DefaultCatchBoundary(10-53)examples/react/start-basic-better-auth/src/components/NotFound.tsx (1)
NotFound(3-25)examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
RouterContext(18-20)
examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (5)
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
Route(28-51)examples/react/start-basic-better-auth/src/routes/index.tsx (1)
Route(3-5)examples/react/start-basic-better-auth/src/routes/login.tsx (1)
Route(4-11)examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
Route(3-10)examples/react/start-basic-better-auth/src/utils/auth.ts (1)
auth(7-25)
examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (3)
e2e/react-start/server-routes/src/components/DefaultCatchBoundary.tsx (1)
DefaultCatchBoundary(10-53)examples/react/start-basic-cloudflare/src/components/DefaultCatchBoundary.tsx (1)
DefaultCatchBoundary(10-53)examples/solid/start-basic-authjs/src/components/DefaultCatchBoundary.tsx (1)
DefaultCatchBoundary(10-53)
examples/react/start-basic-better-auth/src/routes/__root.tsx (7)
examples/react/start-basic-better-auth/src/utils/auth.ts (2)
AuthSession(28-28)auth(7-25)packages/start-server-core/src/request-response.ts (1)
getRequestHeaders(149-152)examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (1)
Route(8-15)examples/react/start-basic-better-auth/src/routes/index.tsx (1)
Route(3-5)examples/react/start-basic-better-auth/src/routes/login.tsx (1)
Route(4-11)examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
Route(3-10)examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)
authClient(3-3)
examples/react/start-basic-better-auth/src/routeTree.gen.ts (1)
examples/react/start-basic-better-auth/src/router.tsx (1)
getRouter(7-19)
examples/react/start-basic-better-auth/src/routes/login.tsx (5)
examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
Route(28-51)examples/react/start-basic-better-auth/src/routes/index.tsx (1)
Route(3-5)examples/react/start-basic-better-auth/src/routes/protected.tsx (1)
Route(3-10)examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)
authClient(3-3)packages/router-core/src/route.ts (1)
path(1590-1592)
🔇 Additional comments (6)
examples/react/start-basic-better-auth/src/styles/app.css (1)
1-1: The@import "tailwindcss";syntax is correct for Tailwind v4.1.18, which is the version specified in this project's package.json. No changes needed.examples/react/start-basic-better-auth/src/utils/auth-client.ts (1)
1-3: No action required—createAuthClient()defaults are correct for this TanStack Start setup. The client is used only in browser context (onClick handlers, client components), and the server uses a separateauthinstance. The defaultbasePathof/api/authmatches your route configuration atroutes/api/auth/$.ts, so explicit configuration is unnecessary.examples/react/start-basic-better-auth/src/routes/__root.tsx (1)
22-26: LGTM! Clean server function implementation.The session fetching logic correctly uses the server-side headers and Better Auth API. Errors naturally propagate to route error boundaries, which is the expected behavior in TanStack Router.
examples/react/start-basic-better-auth/src/routes/api/auth/$.ts (1)
8-15: LGTM! Standard Better Auth API route pattern.The implementation correctly delegates all authentication requests to Better Auth's handler. This is the standard integration pattern and properly handles all auth-related endpoints under
/api/auth/*.examples/react/start-basic-better-auth/src/router.tsx (1)
14-16: LGTM! Type-safe context initialization.The use of
satisfies RouterContextensures type safety while allowing TypeScript to infer the exact type. The initialsession: nullvalue will be properly populated by the root route'sbeforeLoadhook.examples/react/start-basic-better-auth/src/components/DefaultCatchBoundary.tsx (1)
1-53: Matches existing TanStack Start examples; looks good.
Implementation aligns with the repo’s otherDefaultCatchBoundarypatterns (router invalidate + root-aware navigation).
|
I started from the Authjs example and adapted it for Better Auth. |
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
…ress review feedback - Bump internal @tanstack/* and tooling deps to match sibling examples (drop stale ^1.147.0) - Remove unused tailwind-merge and switch to Vite's resolve.tsconfigPaths (drop vite-tsconfig-paths) - auth: add baseURL + trustedOrigins for OAuth/CSRF; validate GitHub env vars instead of non-null assertions - protected: redact debug session output to avoid leaking tokens - root: add error handling to sign-out flow - NotFound: type children as ReactNode instead of any - tsconfig: fix include (drop non-existent env.d.ts) - Format all files with Prettier (single quotes, no semicolons)
baseUrl is deprecated in TS 6 (TS5101) and unnecessary — paths resolve relative to tsconfig. Matches sibling examples (start-basic, start-basic-authjs).
Adds the workspace importer entry and the better-auth@1.6.23 dependency subtree. Purely additive (279 insertions, 0 deletions) — no unrelated nightly/build-stack drift. Verified with a frozen-lockfile install and a successful example build.
|
Hi 👋 This PR adds a TanStack Start + Better Auth example (GitHub OAuth, protected routes, session in the router context). It's structured to mirror the existing I believe it's ready for review:
Two small asks:
cc @Sheraff — saw you maintain the Solid |
This pull request introduces a new example project,
start-basic-better-auth, demonstrating authentication integration between TanStack Start and Better Auth using GitHub OAuth. The project includes all necessary configuration, routing, authentication logic, and supporting documentation. It provides a ready-to-use template for developers to implement secure authentication and protected routes in a React application.Authentication and Session Management:
src/utils/auth.ts, enabling GitHub OAuth and stateless session management via cookies.src/utils/auth-client.tsfor use in React components./api/auth/*to process authentication requests through Better Auth.Routing and Protected Pages:
src/routes/__root.tsx, fetching the session and providing navigation with sign-in/sign-out logic.src/routes/protected.tsxandsrc/routes/login.tsx) that redirect users based on authentication status. [1] [2]Project Structure and Tooling:
package.jsonwith dependencies for TanStack Router/Start, Better Auth, React 19, Tailwind CSS, and Vite tooling.tsconfig.json) and environment variable example (.env.example) for easy setup and development. [1] [2].gitignoreto exclude build artifacts and sensitive files.Documentation and UI Components:
README.mdwith setup instructions, OAuth configuration steps, and key file references for authentication integration.DefaultCatchBoundary.tsx), not found pages (NotFound.tsx), and applies Tailwind CSS styling. [1] [2] [3]This example provides a robust starting point for secure authentication workflows in TanStack Start applications.
Summary by CodeRabbit
Documentation
New Features
✏️ Tip: You can customize this high-level summary in your review settings.